package com.coovane.bytetrix.common.util;

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.List;

/**
 * <p>
 * 日期相关工具类
 * </p>
 *
 * @author: Hsu
 * @date: 2021/7/2 23:11
 * @copyright: companyName
 * @see
 * @since 1.8
 */
public class DateTimeUtils {
    public static final String SHORT_DATE_FORMAT = "yyyy-MM-dd";
    public static final String SHORT_DATE_SLASH = "yyyy/MM/dd";
    public static final String SHORT_DATE_CN = "yyyy年MM月dd日";
    public static final String LONG_DATE_FORMAT = "yyyy-MM-dd HH:mm:ss";
    public static final String YYYYMMDD = "yyyyMMdd";
    public static final String YYYYMMDDHHMMSS = "yyyyMMddHHmmss";
    public static final String YYYY_MM_DD = "yyyy.MM.dd";

    public static List<String> allFormat() {
        ArrayList<String> dateFormat = new ArrayList<>();
        dateFormat.add(SHORT_DATE_FORMAT);
        dateFormat.add(SHORT_DATE_SLASH);
        dateFormat.add(SHORT_DATE_CN);
        dateFormat.add(LONG_DATE_FORMAT);
        dateFormat.add(YYYYMMDD);
        dateFormat.add(YYYYMMDDHHMMSS);
        dateFormat.add(YYYY_MM_DD);
        return dateFormat;
    }

    public static Calendar getLastMonthFirstDay(Calendar time) {
        time.add(2, -1);
        time.set(5, 1);
        time.set(11, 0);
        time.set(12, 0);
        time.set(13, 0);
        return time;
    }

    public static Date getMonthFirstDay(Date date) {
        Calendar time = Calendar.getInstance();
        time.setTime(date);
        time.set(5, 1);
        time.set(11, 0);
        time.set(12, 0);
        time.set(13, 0);
        time.set(14, 0);
        return time.getTime();
    }

    public static int getTodayStartTime() {
        Calendar time = Calendar.getInstance();
        time.set(11, 0);
        time.set(12, 0);
        time.set(13, 0);
        return (int) (time.getTimeInMillis() / 1000L);
    }

    public static Date getDayStartTime(Date date) {
        Calendar time = Calendar.getInstance();
        time.setTime(date);
        time.set(11, 0);
        time.set(12, 0);
        time.set(13, 0);
        return time.getTime();
    }

    public static Date getDayEndTime(Date date) {
        Calendar time = Calendar.getInstance();
        time.setTime(date);
        time.set(11, 24);
        time.set(12, 59);
        time.set(13, 59);
        return time.getTime();
    }

    public static Date getDayStartTime() {
        return getDayStartTime(new Date());
    }

    public static Calendar getLastMonthLastDay(Calendar time) {
        time.set(5, 1);
        time.set(11, 23);
        time.set(12, 59);
        time.set(13, 59);
        time.add(5, -1);
        return time;
    }

    public static Date string2DateShort(String dateStr) {
        return string2Date(dateStr, SHORT_DATE_FORMAT);
    }

    public static Date parse(String dateStr, Date defaultValue) {
        if (dateStr.startsWith("0")) {
            return defaultValue;
        }
        List<String> allFormat = DateTimeUtils.allFormat();
        int length = allFormat.size();
        int i = 0;

        while (i < length) {
            String pattern = allFormat.get(i);

            try {
                SimpleDateFormat formatter = new SimpleDateFormat(pattern);
                return formatter.parse(dateStr);
            } catch (Exception e) {
                ++i;
            }
        }

        if (null != defaultValue) {
            return defaultValue;
        } else {
            throw new RuntimeException("java.text.ParseException: Unparseable date:" + dateStr);
        }
    }

    public static Date string2Date(String dateStr, String format) {
        SimpleDateFormat formatter = new SimpleDateFormat(format);
        dateStr = dateStr == null ? null : dateStr.trim();
        if (dateStr == null) {
            throw new IllegalArgumentException("dateStr is null");
        } else {
            try {
                return formatter.parse(dateStr);
            } catch (ParseException e) {
                throw new RuntimeException(e);
            }
        }
    }

    public static String date2ShortString(Date date) {
        SimpleDateFormat formatter = new SimpleDateFormat(SHORT_DATE_FORMAT);
        return formatter.format(date);
    }

    public static String date2String(Date date) {
        SimpleDateFormat formatter = new SimpleDateFormat(LONG_DATE_FORMAT);
        return formatter.format(date);
    }

    public static String date2String(Date date, String format) {
        SimpleDateFormat formatter = new SimpleDateFormat(format);
        return formatter.format(date);
    }

    public static int unixTime() {
        return (int) (System.currentTimeMillis() / 1000L);
    }

    public static Date fromUnixTime(int seconds) {
        return new Date((long) seconds * 1000L);
    }

    public static Date fromUnixTime(long milliseconds) {
        return new Date(milliseconds);
    }

    public static int day2UnixTime(String day) {
        return (int) (parse(day, null).getTime() / 1000L);
    }

    public static int date2UnixTime(Date date) {
        return (int) (date.getTime() / 1000L);
    }

    public static Date today() {
        return toDay(new Date());
    }

    public static Date toDay(Date date) {
        Calendar cal = Calendar.getInstance();
        cal.setTime(date);
        cal.set(11, 0);
        cal.set(12, 0);
        cal.set(13, 0);
        cal.set(14, 0);
        return cal.getTime();
    }

    public static Date toNight(Date date) {
        Calendar cal = Calendar.getInstance();
        cal.setTime(date);
        cal.set(11, 23);
        cal.set(12, 59);
        cal.set(13, 59);
        cal.set(14, 0);
        return cal.getTime();
    }

    public static Date toYesterday(Date date) {
        return add(date, 6, -1);
    }

    public static Date toTomorrow(Date date) {
        return add(date, 6, 1);
    }

    static Date add(Date date, int field, int value) {
        Calendar cal = Calendar.getInstance();
        cal.setTimeInMillis(date.getTime());
        cal.add(field, value);
        return cal.getTime();
    }

    public static int getYear(Date date) {
        Calendar cal = Calendar.getInstance();
        cal.setTimeInMillis(date.getTime());
        return cal.get(1);
    }

    public static int getMonth(Date date) {
        Calendar cal = Calendar.getInstance();
        cal.setTimeInMillis(date.getTime());
        return cal.get(2) + 1;
    }

    public static int getDayOfWeek(Date date) {
        Calendar cal = Calendar.getInstance();
        cal.setTimeInMillis(date.getTime());
        int dayOfWeek = cal.get(7);
        int rel = -1;
        switch (dayOfWeek) {
            case 2:
                rel = 1;
                break;
            case 3:
                rel = 2;
                break;
            case 4:
                rel = 3;
                break;
            case 5:
                rel = 4;
                break;
            case 6:
                rel = 5;
                break;
            case 7:
                rel = 6;
                break;
            default:
                rel = 7;
        }

        return rel;
    }

    public static boolean isToday(Date date) {
        Date now = new Date();
        SimpleDateFormat sf = new SimpleDateFormat(YYYYMMDD);
        String nowDay = sf.format(now);
        String day = sf.format(date);
        return day.equals(nowDay);
    }

}
